package com.wzdigit.wms.wms.service.order;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzdigit.framework.Shift;
import com.wzdigit.framework.exception.RestStatusException;
import com.wzdigit.mes.basic.api.BasicSimpleCodeRuleApi;
import com.wzdigit.wms.basic.client.request.asn.initial.SubmitInitialInInputRequest;
import com.wzdigit.wms.basic.client.request.trsn.ScanUpCodeRequest;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.client.response.asn.initial.ScanInitialSnResponse;
import com.wzdigit.wms.basic.client.response.basic.RecommendedLocationResponse;
import com.wzdigit.wms.basic.domain.asn.AsnDtl;
import com.wzdigit.wms.basic.domain.asn.AsnDtlGoods;
import com.wzdigit.wms.basic.domain.asn.AsnHeader;
import com.wzdigit.wms.basic.domain.basic.Sku;
import com.wzdigit.wms.basic.domain.dtos.inventory.UpdateInventoryInputDto;
import com.wzdigit.wms.basic.domain.inventory.*;
import com.wzdigit.wms.basic.domain.order.TrsnDtl;
import com.wzdigit.wms.basic.domain.order.TrsnDtlGoods;
import com.wzdigit.wms.basic.domain.order.TrsnHeader;
import com.wzdigit.wms.basic.enums.*;
import com.wzdigit.wms.basic.mapper.core.inventory.SnScanLogMapper;
import com.wzdigit.wms.basic.service.code.InventoryService;
import com.wzdigit.wms.basic.service.code.LotnoService;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.basic.util.StringUtils;
import com.wzdigit.wms.wms.service.basic.LocationService;
import com.wzdigit.wms.wms.service.core.*;
import com.wzdigit.wms.wms.service.core.transfer.TransferUpService;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class InitialStockInService {

	@Autowired
	private SnScanLogMapper snScanLogMapper;
	
	@Autowired
	private SkuCodeService skuCodeService;
	
	@Autowired
	private LotnoService lotnoService;
	
	@Autowired
	private GoodsService goodsService;
	
	@Autowired
	private LocationService locationService;
	
	@Autowired
	private TransferUpService transferUpService;
	
	@Autowired
	private TrsnManagerService trsnManagerService;
	
	@Autowired
	private AsnManagerService asnManagerService;
	
	@Autowired
	private InventoryService inventoryService;
	
    @Reference(version = "${dubbo.consumers.basic.simple.code.rule.api:1.0.0}", check = false)
    private BasicSimpleCodeRuleApi basicSimpleCodeRuleApi;

    private final static String ASN_RULE_CODE = "ASN_R01";
    private final static String PALLET_NO_RULE_CODE = "virtualPalletCode";
    private final static String TRSN_RULE_CODE = "TRSN_ORDER";

    /**
     * 获取sn信息
     * 
     * @param sn
     * @param servletRequest
     * @return
     */
    public Result<ScanInitialSnResponse> scanSn(String sn, HttpServletRequest servletRequest) {
        //1. 获取条码信息
        GoodsTemp goodsTemp = goodsService.selectTempGoodsBySn(sn);
        try {
            if (goodsTemp == null) {
            	Shift.fatal(String.format("没有找到SN[%s]的信息!", sn));
            }
            if (goodsTemp.getWhsId() != null) {
            	Shift.fatal(String.format("SN[%s]已经入库,不允许重复入!", sn));
            }
            if (goodsTemp.getLocId() != null) {
            	Shift.fatal(String.format("SN[%s]已经上架,不允许重复入!", sn));
            }
            if (goodsTemp.getOwner() == null) {
            	Shift.fatal(String.format("当前SN[%s]货主为空!", sn));
            }
            if (StringUtils.isNull(goodsTemp.getFactory())) {
            	Shift.fatal(String.format("当前SN[%s]组织为空!", sn));
            }
            if (StringUtils.isNull(goodsTemp.getSoNo())) {
            	Shift.fatal(String.format("当前SN[%s]销售订单为空!", sn));
            }
            if (StringUtils.isNull(goodsTemp.getSoItem())) {
            	Shift.fatal(String.format("当前SN[%s]销售订单行号为空!", sn));
            }
            if (StringUtils.isNull(goodsTemp.getSkuCode())) {
            	Shift.fatal("初始化数据中的产品编码缺失!");
            }
            
            Sku sku = skuCodeService.getSkuByCode(goodsTemp.getSkuCode());
            if (sku == null) {
            	Shift.fatal("没有找到[" + goodsTemp.getSkuCode() + "]的信息!");
            }

            ScanInitialSnResponse ret = new ScanInitialSnResponse();
            ret.setSkuId(sku.getSkuId());
            ret.setSkuCode(sku.getSkuCode());
            ret.setSkuDesc(sku.getDescCn());
            ret.setCustomerModel(sku.getModel());
            ret.setGoodsSn(goodsTemp.getGoodsSn());
            ret.setPoNo(goodsTemp.getPoNo());
            ret.setSoNo(goodsTemp.getSoNo());
            ret.setSoItem(goodsTemp.getSoItem());
            ret.setQty(goodsTemp.getQty());
            return new Result<>(ret);
        } catch (RestStatusException ex) {
            //记录异常信息
        	String userName = HttpSessionUtil.getLoginName(servletRequest);
            setSnScanLog(sn, userName, ex.getContent());
            throw ex;
        }
    }

    /**
     * 记录异常
     *
     * @param sn
     * @param userName
     * @param errorMsg
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void setSnScanLog(String sn, String userName, String errorMsg) {
        //记录异常信息
        QueryWrapper<SnScanLog> snScanLogQueryWrapper = new QueryWrapper<>();
        snScanLogQueryWrapper.eq("SN", sn);
        snScanLogQueryWrapper.eq("OP_CODE", OpCodeEnum.INVENTORYINIT.getCode());
        List<SnScanLog> snScanLogs = snScanLogMapper.selectList(snScanLogQueryWrapper);
        if (snScanLogs.size() == 0) {
            SnScanLog snScanLog = new SnScanLog();
            snScanLog.setSn(sn);
            snScanLog.setOpCode(OpCodeEnum.INVENTORYINIT.getCode());
            snScanLog.setErrMsg(errorMsg);
            snScanLog.setCreateTime(new Date());
            snScanLog.setCreateUser(userName);
            snScanLogMapper.insert(snScanLog);
        } else {
            SnScanLog snScanLog = snScanLogs.get(0);
            snScanLog.setErrMsg(errorMsg);
            snScanLog.setModifyTime(new Date());
            snScanLog.setModifyUser(userName);
            snScanLogMapper.updateById(snScanLog);
        }
    }

    /**
     * 提交
     * 
     * @param dto
     * @param servletRequest
     * @return
     * @throws Exception 
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<String> submit(SubmitInitialInInputRequest dto, HttpServletRequest servletRequest) throws Exception {
		if (dto.getSnItems().size() == 0) {
			Shift.fatal("请提交对应的sn信息!");
		}
		if (StringUtils.isNull(dto.getLocationCode())) {
			Shift.fatal("请扫描库位!");
		}
		if (dto.getQaStatus() == null) {
			Shift.fatal("请选择QA状态!");
		}
        String userName = HttpSessionUtil.getLoginName(servletRequest);
        
        // 转换：List<List<SN>> => List<SN>
		List<String> snList = dto.getSnItems().stream().flatMap(Collection::stream).collect(Collectors.toList());
		if (snList.size() == 0) {
			Shift.fatal("请提交对应的sn信息!");
		}
		if (snList.size() > snList.stream().distinct().count()) {
			Shift.fatal("传入重复SN数据!");
		}
		
        // 根据SN集合获取条码信息
		List<Goods> allGoodsList = goodsService.selectListByListSn(snList);
		if (allGoodsList.stream().anyMatch(t -> t.getWhsId() != null)) {
			// 存在任意一个条码的仓库不为空
			List<String> whsSnList = allGoodsList.stream().filter(t -> t.getWhsId() != null).map(Goods::getGoodsSn).distinct().collect(Collectors.toList());
			Shift.fatal("以下sn已经在仓库中:[" + String.join(",", whsSnList) + "]");
		}
		
		
		// 根据SN集合获取条码中间表信息
        List<GoodsTemp> allGoodsTempList = goodsService.selectGoodsTempListByListSn(snList);
        // 条码数量 > 条码中间表数量
        if (snList.size() > allGoodsTempList.size()) {
        	List<String> existSn = allGoodsTempList.stream().map(GoodsTemp::getGoodsSn).distinct().collect(Collectors.toList());
        	List<String> notExistSn = snList.stream().filter(t -> !existSn.contains(t)).collect(Collectors.toList());
        	Shift.fatal("以下sn没有找不到信息:[" + String.join(",", notExistSn) + "]");
        }
        
        if (allGoodsTempList.stream().anyMatch(t -> StringUtils.isNull(t.getSkuCode()))) {
        	// 存在任意一个条码的物料编码不存在
            List<String> noSkuCodeSnList = allGoodsTempList.stream().filter(t -> StringUtils.isNull(t.getSkuCode())).map(GoodsTemp::getGoodsSn).distinct().collect(Collectors.toList());
            Shift.fatal("以下sn数据产品编码缺失:[" + String.join(",", noSkuCodeSnList) + "]");
        }
        
        if (allGoodsTempList.stream().anyMatch(t -> t.getWhsId() != null)) {
        	// 存在任意一个条码的仓库不为空
        	List<String> whsGoodsList = allGoodsTempList.stream().filter(t -> t.getWhsId() != null).map(GoodsTemp::getGoodsSn).collect(Collectors.toList());
        	if (whsGoodsList.size() > 0) {
        		Shift.fatal("以下sn已经在仓库中:[" + String.join(",", whsGoodsList) + "]");
        	}
        }
        
        // 获取库位信息和仓库信息
        RecommendedLocationResponse locInfo = locationService.selectWareHouseByLocCode(dto.getLocationCode());
        if (locInfo == null) {
        	Shift.fatal(String.format("没有找到库位[%s]信息!", dto.getLocationCode()));
        }

        Map<String, Integer> skuMap = new HashMap<>();
        for (GoodsTemp t : allGoodsTempList) {
        	Goods goods = null;
        	
        	// 优先查找SN一样的条码
        	if (allGoodsList.stream().anyMatch(c -> c.getGoodsSn().equals(t.getGoodsSn()))) {
        		goods = allGoodsList.stream().filter(c -> c.getGoodsSn().equals(t.getGoodsSn())).findFirst().get();
                goods.setWhsId(locInfo.getWhsId());
                goods.setModifyUser(userName);
                goods.setModifyTime(new Date());
                goods.setQaStatus(dto.getQaStatus());
                goods.setStatus(GoodsStatusEnum.WAIT_UP.getCode());
                if (goods.getLotno() != null) {
                    t.setLotno(goods.getLotno());
                }
                Integer goodsTempId = t.getGoodsId();
                BeanUtil.copy(goods, t);
                t.setGoodsId(goodsTempId);
            } else {
                t.setWhsId(locInfo.getWhsId());
                t.setModifyUser(userName);
                t.setModifyTime(new Date());
                t.setQaStatus(dto.getQaStatus());
                t.setStatus(GoodsStatusEnum.WAIT_UP.getCode());
                //获取物料ID
                Integer skuId = skuMap.get(t.getSkuCode());
                if (skuId == null) {
                	Sku sku = skuCodeService.getSkuByCode(t.getSkuCode());
                    if (sku == null) {
                        Shift.fatal("没有找到[" + t.getSkuCode() + "]的信息!");
                    }
                    skuId = sku.getSkuId();
                    skuMap.put(t.getSkuCode(), skuId);
                }
                t.setSkuId(skuId);
                
                goods = new Goods();
                BeanUtil.copy(t, goods);
                goods.setGoodsId(null);
                allGoodsList.add(goods);
            }
            
            try {
            	//生成lot号
                Lotno lotno = lotnoService.createLotnoByGoods(goods, userName);
                goods.setLotno(lotno.getLotno());
                t.setLotno(lotno.getLotno());
            } catch (Exception e) {
                Shift.fatal("sn[" + t.getGoodsSn() + "]生成Lot号失败!");
            }
		}
        
        // 生成虚拟卡板
        GoodsPkg goodsPkg = setGoodsPkg(userName);
        goodsService.getGoodsPkgMapper().insert(goodsPkg);
        
        goodsPkg.setUrl(String.format("%s_0", goodsPkg.getGoodsPkgId()));
        goodsService.getGoodsPkgMapper().updateUrlByGoodsPkgId(goodsPkg.getGoodsPkgId(), goodsPkg.getUrl());

        // 处理goods数据
        for (Goods goods : allGoodsList) {
            goods.setStockInDate(new Date());
            goods.setModifyTime(new Date());
            goods.setPkgId(goodsPkg.getGoodsPkgId());
            if (goods.getGoodsId() == null) {
            	goodsService.getGoodsMapper().insert(goods);
            } else {
            	goodsService.getGoodsMapper().updateById(goods);
            }
        }
        
        // 处理条码中间表数据
        for (GoodsTemp goodsTemp : allGoodsTempList) {
        	goodsTemp.setModifyTime(new Date());
        	goodsTemp.setPkgId(goodsPkg.getGoodsPkgId());
            goodsService.getGoodsTempMapper().updateById(goodsTemp);
        }
        
        // 保存数据
        saveOrderInfo(allGoodsList, dto.getQaStatus());
        
        // 调用上架服务
        ScanUpCodeRequest inputUp = new ScanUpCodeRequest();
        inputUp.setLocCode(locInfo.getLocCode());
        inputUp.setSnList(snList);
        transferUpService.scanUpCode(inputUp, userName, servletRequest);
        return new Result<>(true, "操作成功!");
//         Shift.fatal("异常回滚, 测试结束!");
//         return null;
    }

    private GoodsPkg setGoodsPkg(String userName) {
        GoodsPkg goodsPkg = new GoodsPkg();
        goodsPkg.setPkgSn(basicSimpleCodeRuleApi.GenerateCode(PALLET_NO_RULE_CODE));
        goodsPkg.setPkgLevel(1);
        goodsPkg.setPkgCategory("PALLET");
        goodsPkg.setPkgType(10);
        goodsPkg.setFatherPkgId(0);
        goodsPkg.setIsLeaf(BooleanEnum.TRUE.getCode());
        goodsPkg.setUrl(String.format("%s_0", goodsPkg.getGoodsPkgId()));
        goodsPkg.setCreateTime(new Date());
        goodsPkg.setModifyTime(new Date());
        goodsPkg.setCreateUser(userName);
        goodsPkg.setModifyUser(userName);
        return goodsPkg;
    }

    private void saveOrderInfo(List<Goods> goodsList, Integer qaStatus) throws Exception {
    	if(goodsList.size() == 0) {
    		return;
    	}
        //3. 写入数据
        //3.1 生成收货单
        AsnHeader asnHeader = setAsnHeader(goodsList.get(0));
        List<AsnDtl> asnDtlList = new ArrayList<>();
        List<List<AsnDtlGoods>> asnDtlGoodsList = new ArrayList<>();

        // 生成入库凭证
        TrsnHeader trsnHeader = setTrsnHeader(asnHeader);
        List<TrsnDtl> trsnDtlList = new ArrayList<>();
        List<List<TrsnDtlGoods>> trsnDtlGoodsList = new ArrayList<>();
        List<UpdateInventoryInputDto> invInList = new ArrayList<>();
        List<InvTrans> invLogs = new ArrayList<>();
        //3.2 生成收货明细 / 3.3 生成收货明细SN信息
        Map<String, List<Goods>> collect = goodsList.stream().collect(
                Collectors.groupingBy(t -> t.getWhsId() + "#" + t.getLocId() + "#" + t.getOwner() + "#" + 
                		t.getSkuId() + "#" + t.getFactory() + "#" + t.getVendorId() + "#" + t.getLotno() + "#" + 
                		t.getInvAttr() + "#" + t.getQaStatus() + "#", Collectors.toList()));
        int index = 0;
        for (String key : collect.keySet()) {
            index++;
            List<Goods> goodsCollect = collect.get(key);
            //生成收货明细
            AsnDtl asnDtl = setAsnDtl(asnHeader, goodsCollect);
            BigDecimal qty = goodsCollect.stream().map(Goods::getQty).reduce(BigDecimal.ZERO, BigDecimal::add);
            asnDtl.setQaStatus(qaStatus);
            asnDtl.setQcStatus(asnHeader.getQcStatus());
            asnDtl.setAsnLineNo(String.valueOf(index));
            asnDtl.setOrderQty(qty);
            asnDtl.setOrderQtyEa(qty);
            asnDtl.setRcvQty(qty);
            asnDtl.setRcvQtyEa(qty);
            asnDtl.setModifyTime(new Date());
            asnDtlList.add(asnDtl);
            //生成收货明细SN信息
            asnDtlGoodsList.add(setAsnDtlGoods(asnDtl, goodsCollect));
            // 生成入库凭证明细
            TrsnDtl trsnDtl = setTrsnDtl(asnHeader, asnDtl);
            trsnDtl.setNoteNo(trsnHeader.getNoteNo());
            trsnDtl.setNoteLineNo(trsnHeader.getNoteNo());
            trsnDtlList.add(trsnDtl);
            // 生成入库凭证明细SN信息
            trsnDtlGoodsList.add(setTrsnDtlGoods(trsnDtl, goodsCollect));

            UpdateInventoryInputDto inventoryInputDto = new UpdateInventoryInputDto();
            inventoryInputDto.setWhsId(asnDtl.getWhsId());
            inventoryInputDto.setOwner(asnHeader.getOwner());
            inventoryInputDto.setSkuId(goodsCollect.get(0).getSkuId());
            inventoryInputDto.setFactory(asnHeader.getFactory());
            inventoryInputDto.setVendorId(asnHeader.getVendorId());
            inventoryInputDto.setLotNo(goodsCollect.get(0).getLotno());
            inventoryInputDto.setInvAttr(goodsCollect.get(0).getInvAttr());
            inventoryInputDto.setQaStatus(goodsCollect.get(0).getQaStatus());
            inventoryInputDto.setQty(goodsCollect.stream().map(Goods::getQty).reduce(BigDecimal.ZERO, BigDecimal::add));
            inventoryInputDto.setUnit(goodsCollect.get(0).getUnit());
            inventoryInputDto.setOperator(asnDtl.getModifyUser());
            invInList.add(inventoryInputDto);

            InvTrans log = new InvTrans();
            log.setOpCode(OpCodeEnum.RECEIVE.getCode());
            log.setDocType(asnHeader.getAsnType());
            log.setDocNo(asnDtl.getAsnNo());
            log.setDocLineNo(asnDtl.getAsnLineNo());
            log.setTrsnNo(trsnHeader.getNoteNo());
            log.setTrsnLineNo(trsnDtl.getNoteLineNo());
            log.setStatus(InvTransStatusEnum.FINISHED.getCode());
            log.setTransTime(new Date());
            log.setOperator(asnDtl.getModifyUser());
            log.setTransQty(asnDtl.getRcvQty());
            log.setCreateTime(new Date());
            log.setModifyTime(new Date());
            log.setCreateUser(asnDtl.getModifyUser());
            log.setModifyUser(asnDtl.getModifyUser());
            invLogs.add(log);
        }
        //保存数据
        asnHeader.setStatus(AsnHeaderStatusEnum.FINISH.getCode());
        asnManagerService.getAsnHeaderService().addNewOne(asnHeader);
        trsnHeader.setStatus(TrsnHeaderStatusEnum.CMP.getCode());
        trsnManagerService.getTrsnHeaderMapper().insert(trsnHeader);
        for (int i = 0; i < asnDtlList.size(); i++) {
            AsnDtl asnDtl = asnDtlList.get(i);
            asnDtl.setAsnLineNo(String.valueOf(i + 1));
            asnDtl.setAsnHeaderId(asnHeader.getAsnHeaderId());
            asnDtl.setStatus(AsnDtlStatusEnum.FINISH.getCode());
            asnManagerService.getAsnDtlService().addNewOne(asnDtl);
            TrsnDtl trsnDtl = trsnDtlList.get(i);
            trsnDtl.setTrsnHeaderId(trsnHeader.getTrsnHeaderId());
            trsnDtl.setFmDoc(asnHeader.getAsnNo());
            trsnDtl.setFmDocLine(asnDtl.getAsnLineNo());
            trsnManagerService.getTrsnDtlMapper().insert(trsnDtl);
            asnDtlGoodsList.get(i).forEach(t -> {
                t.setAsnDtlId(asnDtl.getAsnDtlId());
                asnManagerService.getAsnDtlGoodsService().addNewOne(t);
            });
            trsnDtlGoodsList.get(i).forEach(t -> {
                t.setTrsnDtlId(trsnDtl.getTrsnDtlId());
                trsnManagerService.getTrsnDtlGoodsMapper().insert(t);
            });
            //库存操作
            inventoryService.inventoryIn(invInList.get(i), invLogs.get(i));
        }
    }

    private List<TrsnDtlGoods> setTrsnDtlGoods(TrsnDtl trsnDtl, List<Goods> listGoods) {
        List<TrsnDtlGoods> list = new ArrayList<>();
        for (Goods goods : listGoods) {
            TrsnDtlGoods item = new TrsnDtlGoods();
            item.setGoodsId(goods.getGoodsId());
            item.setGoodsSn(goods.getGoodsSn());
            item.setQaStatus(goods.getQaStatus());
            item.setQty(goods.getQty());
            item.setComments("");
            item.setStatus(TrsnDtlGoodsStatusEnum.RECEIVED.getCode());
            item.setQaStatus(goods.getQaStatus());
            item.setCreateUser(trsnDtl.getModifyUser());
            item.setModifyUser(trsnDtl.getModifyUser());
            item.setCreateTime(new Date());
            item.setModifyTime(new Date());
            list.add(item);
        }
        return list;
    }

    private TrsnDtl setTrsnDtl(AsnHeader asnHeader, AsnDtl asnDtl) {
        TrsnDtl item = new TrsnDtl();

        item.setNoteLineNo(asnDtl.getAsnLineNo());
        item.setInvUpdateFlag(TrsnDtlInvUpdateFlagEnum.IN.getCode());
        item.setFmDoc(asnDtl.getAsnNo());
        item.setFmDocLine(asnDtl.getAsnLineNo());
        item.setSkuId(asnDtl.getSkuId());
        item.setQty(asnDtl.getRcvQty());
        item.setUnit(asnDtl.getUnit());

        item.setQaStatus(asnDtl.getQaStatus());

        item.setInvAttr(asnDtl.getInvAttr());
        item.setLotAttr1(asnDtl.getLotAttr1());
        item.setLotAttr2(asnDtl.getLotAttr2());
        item.setLotAttr3(asnDtl.getLotAttr3());
        item.setLotAttr4(asnDtl.getLotAttr4());
        item.setLotAttr5(asnDtl.getLotAttr5());
        item.setLotAttr6(asnDtl.getLotAttr6());
        item.setLotAttr7(asnDtl.getLotAttr7());
        item.setLotAttr8(asnDtl.getLotAttr8());
        item.setLotAttr9(asnDtl.getLotAttr9());
        item.setLotAttr10(asnDtl.getLotAttr10());
        item.setLotAttr11(asnDtl.getLotAttr11());
        item.setLotAttr12(asnDtl.getLotAttr12());
        item.setStatus(TrsnDtlStatusEnum.CMP.getCode());
        item.setCreateTime(new Date());
        item.setModifyTime(new Date());
        item.setModifyUser(asnHeader.getModifyUser());
        item.setCreateUser(asnHeader.getModifyUser());
        return item;
    }

    /*赋值 TrsnHeader*/
    private TrsnHeader setTrsnHeader(AsnHeader asnHeader) {
        TrsnHeader item = new TrsnHeader();
        item.setNoteNo(basicSimpleCodeRuleApi.GenerateCode(TRSN_RULE_CODE));
        item.setNoteType(TrsnNoteTypeEnum.IN_STORAGE.getCode()); //凭证类型
        item.setOwner(asnHeader.getOwner());
        item.setFactory(asnHeader.getFactory());
        item.setWhsId(asnHeader.getToWhs());
        item.setVendorId(asnHeader.getVendorId());
        item.setFmDoc(asnHeader.getAsnNo()); //来源单据
        item.setStatus(TrsnHeaderStatusEnum.CMP.getCode());
        item.setCreateTime(new Date());
        item.setModifyTime(new Date());
        item.setDocRef1(asnHeader.getAsnRef1());
        item.setDocRef2(asnHeader.getAsnRef2());
        item.setDocRef3(asnHeader.getAsnRef3());
        item.setDocRef4(asnHeader.getAsnRef4());
        item.setDocRef5(asnHeader.getAsnRef5());
        item.setModifyUser(asnHeader.getModifyUser());
        item.setCreateUser(asnHeader.getModifyUser());
        return item;
    }

    private List<AsnDtlGoods> setAsnDtlGoods(AsnDtl asnDtl, List<Goods> listGoods) {
        List<AsnDtlGoods> listAsnDtlGoods = new ArrayList<>();
        for (Goods goods : listGoods) {
            AsnDtlGoods item = new AsnDtlGoods();
            //item.setAsnDtlId(asnItem.getAsnDtlId());
            item.setGoodsId(goods.getGoodsId());
            item.setGoodsSn(goods.getGoodsSn());
            item.setQaStatus(goods.getQaStatus());
            item.setQty(goods.getQty());
            item.setComments("");
            item.setStatus(AsnDtlGoodsStatusEnum.HAS_RECEIVE.getCode());
            item.setCreateUser(asnDtl.getCreateUser());
            item.setModifyUser(asnDtl.getCreateUser());
            item.setCreateTime(new Date());
            item.setModifyTime(new Date());
            listAsnDtlGoods.add(item);
        }
        return listAsnDtlGoods;

    }

    private AsnHeader setAsnHeader(Goods firstGoods) {
        AsnHeader asnHeader = new AsnHeader();
        //1. 设置asnHeader
        asnHeader.setAsnNo(basicSimpleCodeRuleApi.GenerateCode(ASN_RULE_CODE));  //单号
        asnHeader.setAsnType(AsnTypeEnum.R98.getCode());
        asnHeader.setPriority(0);
        asnHeader.setOwner(firstGoods.getOwner());
        asnHeader.setAsnCreateTime(new Date());
        asnHeader.setExpectArriveTime1(new Date());
        asnHeader.setFactory(firstGoods.getFactory());
        asnHeader.setToWhs(firstGoods.getWhsId());
        asnHeader.setVendorId(firstGoods.getVendorId());
        asnHeader.setPoNo(firstGoods.getPoNo());
        asnHeader.setDataSource("ERP");
        asnHeader.setReleaseStatus(BooleanEnum.FALSE.getCode());
        asnHeader.setAsnPrintFlag(BooleanEnum.FALSE.getCode());
        asnHeader.setQcStatus(QcStatusEnum.全部质检.getCode());  //判定结果
        asnHeader.setReleaseStatus(1);
        asnHeader.setRcvOverFlag(1);
        asnHeader.setSnScan(BooleanEnum.FALSE.getCode());
        asnHeader.setRcvOverFlag(BooleanEnum.FALSE.getCode());
        asnHeader.setStatus(AsnHeaderStatusEnum.FINISH.getCode());
        asnHeader.setCreateUser(firstGoods.getModifyUser());
        asnHeader.setModifyUser(firstGoods.getModifyUser());
        asnHeader.setCreateTime(new Date());
        asnHeader.setModifyTime(new Date());
        return asnHeader;
    }

    private AsnDtl setAsnDtl(AsnHeader asnHeader, List<Goods> goodsList) {
        Goods goodsItem = goodsList.get(0);
        Lotno lotInfo = lotnoService.selectByLotno(goodsItem.getLotno());
        Sku sku = skuCodeService.getSkuById(goodsItem.getSkuId());
        if (lotInfo == null) {
        	Shift.fatal("没有找到批次属性信息!");
        }

        AsnDtl asnItem = new AsnDtl();
        asnItem.setAsnNo(asnHeader.getAsnNo());
        asnItem.setAsnLineNo("0");

        asnItem.setPoNo(goodsItem.getPoNo());

        asnItem.setSkuId(sku.getSkuId());
        asnItem.setSkuDesc(sku.getDescCn());
        asnItem.setSkuDescEn(sku.getDescEn());
        asnItem.setSoNo(goodsItem.getSoNo());
        asnItem.setSoLineNo(goodsItem.getSoItem());

        asnItem.setLotno(goodsItem.getLotno());

        asnItem.setOrderQty(BigDecimal.ZERO);
        asnItem.setOrderQtyEa(BigDecimal.ZERO);

        asnItem.setRcvQty(BigDecimal.ZERO);
        asnItem.setRcvQtyEa(BigDecimal.ZERO);

        asnItem.setUnit(sku.getBaseUnit());
        asnItem.setInvAttr(goodsItem.getInvAttr());

        asnItem.setRcvTime(new Date());
        asnItem.setRcvLocId(null);
        asnItem.setPlanLocId(null);

        asnItem.setReserveLocFlag(null);
        asnItem.setInvAttr(goodsItem.getInvAttr());
        asnItem.setInvType(null);

        asnItem.setWhsId(asnHeader.getToWhs());

        asnItem.setQcStatus(QcStatusEnum.已创建质检单.getCode());
        asnItem.setQaStatus(QaStatusEnum.WAIT.getCode());

        //asnItem.setInspNo(goodsItem.getInspNo());

        asnItem.setLotAttr1(lotInfo.getLotAttr1());
        asnItem.setLotAttr2(lotInfo.getLotAttr2());
        asnItem.setLotAttr3(lotInfo.getLotAttr3());
        asnItem.setLotAttr4(lotInfo.getLotAttr4());
        asnItem.setLotAttr5(lotInfo.getLotAttr5());
        asnItem.setLotAttr6(lotInfo.getLotAttr6());
        asnItem.setLotAttr7(lotInfo.getLotAttr7());
        asnItem.setLotAttr8(lotInfo.getLotAttr8());
        asnItem.setLotAttr9(lotInfo.getLotAttr9());
        asnItem.setLotAttr10(lotInfo.getLotAttr10());
        asnItem.setLotAttr11(lotInfo.getLotAttr11());
        asnItem.setLotAttr12(lotInfo.getLotAttr12());
        asnItem.setDataSource("ERP");

        asnItem.setStatus(AsnDtlStatusEnum.CREATE.getCode());
        asnItem.setCreateUser(goodsItem.getModifyUser());
        asnItem.setCreateTime(new Date());
        asnItem.setModifyUser(goodsItem.getModifyUser());
        return asnItem;
    }
}
